﻿using System;
using SassAndCoffee;
using Telerik.Web.Mvc.Extensions;
using Telerik.Web.Mvc.Infrastructure;

namespace Telerik.Web.Mvc.UI {
    public abstract class SassAndCoffeeCollectionBuilder : WebAssetCollectionBuilder {
        private readonly WebAssetCollection assets;
        private readonly ISimpleFileCompiler compiler;

        public SassAndCoffeeCollectionBuilder(WebAssetType assetType, WebAssetCollection assets, ISimpleFileCompiler compiler)
            : base(assetType, assets) {
            this.assets = assets;
            this.compiler = compiler;
        }

        protected abstract string GetFilesPath();

        /// <summary>
        /// Adds a new web asset
        /// </summary>
        /// <param name="source">The source.</param>
        /// <example>
        /// <code lang="CS">
        /// &lt;%= Html.Telerik().ScriptRegistrar()
        ///            .Scripts(scripts => scripts.Add("script1.js"))
        /// %&gt;
        /// </code>
        /// </example>
        public virtual SassAndCoffeeCollectionBuilder Add(string source) {
            assets.Add(Utility.Compile(source, GetFilesPath(), compiler));

            return this;
        }

        /// <summary>
        /// Adds a new web asset group.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <param name="configureAction">The configure action.</param>
        /// <example>
        /// <code lang="CS">
        /// &lt;%= Html.Telerik().ScriptRegistrar()
        ///            .Scripts(scripts => scripts.AddGroup("Group1", group =>
        ///                 {
        ///                     group.Add("script1.js");
        ///                 }
        ///            ))
        /// %&gt;
        /// </code>
        /// </example>
        public virtual SassAndCoffeeCollectionBuilder AddGroup(string name, Action<SassAndCoffeeGroupBuilder> configureAction) {
            Guard.IsNotNullOrEmpty(name, "name");
            Guard.IsNotNull(configureAction, "configureAction");

            WebAssetGroup itemGroup = assets.FindGroupByName(name);

            if(itemGroup != null) {
                throw new ArgumentException("Group with specified name \"{0}\" already exists. Please specify a different name.".FormatWith(name));
            }

            itemGroup = new WebAssetGroup(name, false) { DefaultPath = assets.DefaultPath };
            assets.Add(itemGroup);

            SassAndCoffeeGroupBuilder builder = new SassAndCoffeeGroupBuilder(itemGroup, compiler);
            configureAction(builder);

            return this;
        }

        /// <summary>
        /// Adds the specified shared group.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <example>
        /// <code lang="CS">
        /// &lt;%= Html.Telerik().ScriptRegistrar()
        ///            .Scripts(scripts => scripts.AddShareGroup("SharedGroup1"))
        /// %&gt;
        /// </code>
        /// </example>
        public virtual WebAssetCollectionBuilder AddSharedGroup(string name) {
            base.AddSharedGroup(name);

            return this;
        }

        /// <summary>
        /// Executes the provided delegate that is used to configure the group fluently.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <param name="configureAction">The configure action.</param>
        public virtual SassAndCoffeeCollectionBuilder GetGroup(string name, Action<WebAssetGroupBuilder> configureAction) {
            base.GetGroup(name, configureAction);

            return this;
        }
    }
}